package com.hitqz.robot.biz.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Maps;
import com.hitqz.robot.api.business.dto.PatrolResultExcelDto;
import com.hitqz.robot.api.business.entity.PatrolResultEntity;
import com.hitqz.robot.api.business.model.vo.patrol.LineChartVo;
import com.hitqz.robot.api.business.params.QueryPatrolChartParams;
import com.hitqz.robot.api.business.params.QueryPatrolSummaryParams;
import com.hitqz.robot.api.business.util.ExcelUtil;
import com.hitqz.robot.api.business.vo.PatrolResultSummaryVo;
import com.hitqz.robot.api.business.vo.PatrolResultVo;
import com.hitqz.robot.api.common.entity.PatrolCheckType;
import com.hitqz.robot.api.common.entity.PatrolItem;
import com.hitqz.robot.api.common.entity.PatrolObject;
import com.hitqz.robot.biz.core.FileProperties;
import com.hitqz.robot.biz.service.PatrolCheckTypeService;
import com.hitqz.robot.biz.service.PatrolItemService;
import com.hitqz.robot.biz.service.PatrolObjectService;
import com.hitqz.robot.biz.service.PatrolResultService;
import com.hitqz.robot.common.core.util.R;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;

/**
 * @author wengyx
 * @date 2024/8/7
 */

@RestController
@AllArgsConstructor
@RequestMapping("/patrolResult")
@Tag(name = "巡检结果管理")
public class PatrolResultController {

    final private PatrolResultService patrolResultService;

    final private PatrolItemService patrolItemService;

    final private PatrolObjectService patrolObjectService;

    final private PatrolCheckTypeService patrolCheckTypeService;

    private final FileProperties fileProperties;

    private final ExecutorService customThreadPool;

    @PostMapping("/summary/page")
    @Operation(summary = "分页查询巡检总览")
    public R<Page<PatrolResultSummaryVo>> summaryPage(@RequestBody QueryPatrolSummaryParams query){
        Page page = new Page<>(query.getCurrent(),query.getSize());
        Page<PatrolResultSummaryVo> voPage= patrolResultService.summaryPage(page,query);
        return R.ok(voPage);
    }

    @PostMapping("/summary/{ticketsId}")
    @Operation(summary = "分页查询巡检详情")
    public R<Page<PatrolResultVo>> summaryPage(@PathVariable("ticketsId") Integer ticketsId,@RequestBody QueryPatrolSummaryParams query){
        Page page = new Page<>(query.getCurrent(),query.getSize());
        Page<PatrolResultEntity> data= patrolResultService.page(page, Wrappers.<PatrolResultEntity>lambdaQuery().eq(PatrolResultEntity::getTicketsId,ticketsId).orderByAsc(PatrolResultEntity::getId));
        List<PatrolResultVo> voList = BeanUtil.copyToList(data.getRecords(), PatrolResultVo.class);
        Page<PatrolResultVo> voPage = new Page<>();
        BeanUtil.copyProperties(data,voPage);
        voPage.setRecords(voList);
        return R.ok(voPage);
    }

    @PostMapping("/chart/line")
    @Operation(summary = "折线图数据")
    public R<LineChartVo> line(@RequestBody QueryPatrolChartParams query ){
        List<PatrolResultEntity> list = patrolResultService.list(Wrappers.<PatrolResultEntity>lambdaQuery()
                .ge(StrUtil.isNotBlank(query.getStartTime()),PatrolResultEntity::getCheckTime, query.getStartTime())
                .le(StrUtil.isNotBlank(query.getEndTime()),PatrolResultEntity::getCheckTime, query.getEndTime())
                .eq(PatrolResultEntity::getItemId, query.getItemId()));//按id进行分类
        if (list==null || list.isEmpty()){
            return R.ok(null,"暂无数据");
        }
        PatrolObject object = patrolObjectService.getById(list.get(0).getPatrolObjectId());
        PatrolCheckType checkType = patrolCheckTypeService.getById(object.getPatrolCheckTypeId());
        PatrolItem item = patrolItemService.getById(query.getItemId());
        LineChartVo lineChartVo = new LineChartVo();
        lineChartVo.setItemName(item.getName());
        lineChartVo.setIsEnum(0);
        //枚举类处理
        HashMap<String, String> map = Maps.newHashMap();
        if (Objects.equals(checkType.getResultType(),"2") || Objects.equals(checkType.getResultType(),"3")){
            lineChartVo.setIsEnum(1);
            String[] key = object.getEnumResult().trim().split(",");
            String[] value = object.getEnumConvert().trim().split(",");
            for (int i = 0; i < key.length; i++) {
                map.put(key[i],value[Math.min(i,value.length-1)]);
            }
        }
        lineChartVo.setMap(map);
        lineChartVo.setY( list.stream().map(PatrolResultEntity::getConvertValue).toArray(String[]::new));
        lineChartVo.setX(list.stream().map(PatrolResultEntity::getCheckTime).map(f->DateUtil.format(f,"yyyy-MM-dd HH:mm:ss")).toArray(String[]::new));
        return R.ok(lineChartVo);
    }

    @Operation(summary = "修改巡检结果" , description = "修改巡检结果" )
    @PutMapping
    public R updateById(@RequestBody PatrolResultEntity patrolResult) {
        return R.ok(patrolResultService.updateById(patrolResult));
    }



    @GetMapping("/summary/{ticketsId}/export")
    @Operation(summary = "导出巡检报告")
    public void export(@PathVariable("ticketsId") Integer ticketsId,HttpServletResponse response) throws IOException {
        //查询是否有生成文件（任务完成后自动生成，避免大任务的文件写入时间等待）
        String patrolExcelFilePath = ExcelUtil.getPatrolExcelFilePath(fileProperties.getLocal().getBasePath(), ticketsId);
        if (FileUtil.exist(patrolExcelFilePath)) {
            File file = new File(patrolExcelFilePath);
            if (!file.canWrite()){
                ExcelUtil.response2Web(response,"文件正在写入，请稍后重试");
                return;
            }
            //给前端返回文件
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("智能巡检机器人巡检报告", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(FileUtil.readBytes(patrolExcelFilePath));
            outputStream.close();
        }else {
            //本地写文件
            //查询数据
            CompletableFuture.runAsync(()->{
                QueryPatrolSummaryParams query = new QueryPatrolSummaryParams();
                query.setTicketsId(ticketsId);
                PatrolResultSummaryVo summary = patrolResultService.summary(query);
                List<PatrolResultEntity> data = patrolResultService.list(Wrappers.<PatrolResultEntity>lambdaQuery().eq(PatrolResultEntity::getTicketsId, ticketsId));
                List<PatrolResultExcelDto> list = new ArrayList<>();
                //属性替换
                for (int i = 0; i < data.size(); i++) {
                    PatrolResultEntity patrolResult = data.get(i);
                    PatrolResultExcelDto excelDto = BeanUtil.copyProperties(patrolResult, PatrolResultExcelDto.class);
                    excelDto.setIndex(i+1);//序号
                    String url = StrUtil.isBlank(patrolResult.getVisionMediaUrl()) ? patrolResult.getMediaUrl() : patrolResult.getVisionMediaUrl();
                    excelDto.setPath(fileProperties.getLocal().getBasePath()+ File.separator+url);//文件采用相对路径，所以要加前缀
                    list.add(excelDto);
                }
                //动态表头
                List<List<String>> headTitles = ExcelUtil.head(summary);
                //写文件
                EasyExcel.write(patrolExcelFilePath, PatrolResultExcelDto.class)
                        // 这里放入动态头
                        .head(headTitles)
                        .sheet("Sheet1")
                        .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                        // 当然这里数据也可以用 List<List<String>> 去传入
                        .doWrite(list);
            },customThreadPool);
            ExcelUtil.response2Web(response,"开始生成报表，请稍后重试");
        }
    }

 


    
}
